﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zeta.Bot;
using Zeta.Bot.Settings;
using Zeta.Common;
using Zeta.Game;
using Zeta.Game.Internals.Actors;

namespace KadalaSpree.XCore
{
    public static partial class X
    {
        public static class Inventory
        {
            private static int LastRawBackpackCount { get; set; }
            private static bool LastIsFreeBackPackSlotsResult { get; set; }

            /// <summary>
            /// Checks if there is a valid 2-slot space in backpack
            /// </summary>
            public static bool IsFreeBackPackSlots
            {
                get
                {
                    var slotsUsed = new bool[10, 6];
                    var result = false;
                    var items = ZetaDia.Me.Inventory.Backpack.Where(i => i.IsValid).ToList();
					
					// Temporary measure until this method is fixed
                    if (ZetaDia.Me.Inventory.NumFreeBackpackSlots <= 10)
                        return false;					

                    // If the number of items in backpack hasnt changed, dont bother rechecking each slot.
                    if (LastRawBackpackCount == items.Count)
                        return LastIsFreeBackPackSlotsResult;                    

                    // Ignore items in protected bag slots
                    foreach (var square in CharacterSettings.Instance.ProtectedBagSlots)
                    {
                        slotsUsed[square.Column, square.Row] = true;
                    }

                    foreach (var item in items)
                    {
                        int x = item.InventoryColumn, y = item.InventoryRow;
                        slotsUsed[x, y] = true;

                        if (item.IsTwoSquareItem)
                        {
                            slotsUsed[x, y + 1] = true;
                        }
                    }

                    Action checkAllSlots = delegate
                    {
                        for (int x = 0; x < 10; x++)
                        {
                            for (int y = 0; y < 5; y++) // Only checking 5 rows, for 2 slot items
                            {
                                if (slotsUsed[x, y])
                                    continue;

                                if (slotsUsed[x, y + 1])
                                    continue;

                                result = true;
                                return;
                            }
                        }
                    };
                    checkAllSlots();

                    LastRawBackpackCount = items.Count;
                    LastIsFreeBackPackSlotsResult = result;
                    return result;
                }
            }

            public static int BackPackItemCount
            {
                get { return ZetaDia.Me.Inventory.Backpack.Count(i => i.IsValid); }
            }

            public static bool IsDirty
            {
                get
                {
                    if (!X.Player.IsValid) return false;

                    // There should be nothing but potions in the backpack after town run is complete. 
                    var nonPotions = ZetaDia.Me.Inventory.Backpack.Where(i => i.ItemType != ItemType.Potion).ToList();
                    var nonPotionCount = 0;

                    if (nonPotions.Any())
                    {
                        nonPotionCount = nonPotions.Count();

                        var backpackSlotBlocked = new bool[10, 6];

                        foreach (InventorySquare square in CharacterSettings.Instance.ProtectedBagSlots)
                        {
                            backpackSlotBlocked[square.Column, square.Row] = true;
                        }

                        foreach (var item in nonPotions)
                        {
                            int row = item.InventoryRow;
                            int col = item.InventoryColumn;

                            if (backpackSlotBlocked[col, row])
                            {
                                nonPotionCount--;
                            }
                        }

                    }

                    return (nonPotionCount > 0);
                }

            }





        }
    }
}
